package com.jfok.server.service;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Transient;

import net.sf.json.JSONArray;
import net.sf.json.JSONSerializer;
import net.sf.json.JsonConfig;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.annotations.Formula;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.jfok.server.DAO.ModuleDAO;
import com.jfok.server.DAO.SystemBaseDAO;
import com.jfok.server.DAO.SystemFrameDAO;
import com.jfok.server.common.ModuleServiceFunction;
import com.jfok.server.common.annotation.FieldDefine;
import com.jfok.server.common.annotation.TableDefine;
import com.jfok.server.hibernate.superclass._ApproveAbstract;
import com.jfok.server.hibernate.superclass._AuditingAbstract;
import com.jfok.server.hibernate.superclass._InputInfoAbstract;
import com.jfok.server.hibernate.system._Module;
import com.jfok.server.hibernate.system._ModuleDetailScheme;
import com.jfok.server.hibernate.system._ModuleField;
import com.jfok.server.hibernate.system._ModuleFormScheme;
import com.jfok.server.hibernate.system._ModuleFormSchemeGroup;
import com.jfok.server.hibernate.system._ModuleFormSchemeGroupField;
import com.jfok.server.hibernate.system._ModuleGridNavigate;
import com.jfok.server.hibernate.system._ModuleGridScheme;
import com.jfok.server.hibernate.system._ModuleGridSchemeGroup;
import com.jfok.server.hibernate.system._ModuleGridSchemeGroupField;
import com.jfok.server.hibernate.system._ModuleGroup;
import com.jfok.shared.FieldType;
import com.jfok.shared.TreeNodeRecord;
import com.jfok.shared.TreeNodeRecordChecked;
import com.jfok.shared.module.FieldAggregationType;
import com.jfok.shared.service.ISystemFrameService;

@Service
public class SystemFrameService implements ISystemFrameService {

	private static final Log log = LogFactory.getLog(SystemFrameService.class);

	@Resource
	private SystemBaseDAO systemBaseDAO;

	@Resource
	private SystemFrameDAO systemFrameDAO;

	@Resource
	private ModuleDAO moduleDAO;

	
	@Transactional(propagation = Propagation.REQUIRED)
	public Integer refreshNavigateModule(String moduleId) {

		_Module module = SystemAndLoginInfoService.getModuleWithId(moduleId);
		@SuppressWarnings("unchecked")
		List<_ModuleGridNavigate> navigates = (List<_ModuleGridNavigate>) systemBaseDAO.findByProperty(
				_ModuleGridNavigate.class, "tf_Module.tf_moduleId", moduleId);
		int maxorder = 0;
		int count = 0;
		for (_ModuleGridNavigate na : navigates)
			if (maxorder < na.getTf_order())
				maxorder = na.getTf_order();
		maxorder++;
		for (_ModuleGridNavigate info : module.getCanNavigatePaths()) {
			boolean found = false;
			for (_ModuleGridNavigate na : navigates)
				if (na.getTf_fields().equals(info.getTf_fields())) {
					found = true;
					break;
				}
			if (!found) {
				_ModuleGridNavigate newNavigate = new _ModuleGridNavigate();
				newNavigate.setTf_Module(module);
				newNavigate.setTf_fields(info.getTf_fields());
				newNavigate.setTf_enabled(true);
				newNavigate.setTf_cascading(true);
				newNavigate.setTf_text(info.getTf_text());
				newNavigate.setTf_order(maxorder++);
				count++;
				systemBaseDAO.save(newNavigate);
			}
		}
		return count;
	}

	
	@Transactional(propagation = Propagation.REQUIRED)
	@Override
	public Integer refreshModuleField(String moduleId) {
		_Module module = (_Module) systemBaseDAO.findByPropertyFirst(_Module.class, _Module.MODULEID,
				moduleId);
		String moduleName = module.getTf_moduleName();
		Class<?> beanClass = ModuleServiceFunction.getModuleBeanClass(moduleName);
		if (beanClass == null)
			return -1;
		TableDefine tableDefine = (TableDefine) beanClass.getAnnotation(TableDefine.class);
		if (tableDefine == null)
			return -1;
		// 取得本模块的字段的最大ＩＤ号
		Integer maxId = systemFrameDAO.getMaxModuleFieldId(module.getTf_moduleId());
		int result = refreshModuleField(beanClass, module, maxId);
		return result;
	}

	//
	private Integer refreshModuleField(Class<?> beanClass, _Module module, Integer maxId) {

		// 每一个数据库里没有的字段写入数据库
		int i = 0;
		Field[] fs = beanClass.getDeclaredFields();
		for (Field f : fs) {
			if (!f.getName().startsWith("tf_"))
				continue;
			if (f.getAnnotation(Transient.class) != null)
				continue;
			if (f.getAnnotation(FieldDefine.class) == null)
				continue;

			// module的idkeyfield
			Id id = f.getAnnotation(Id.class);
			if (id != null && !f.getName().equals(module.getTf_primaryKey())) {
				module.setTf_primaryKey(f.getName());
				systemBaseDAO.attachDirty(module, null);
			}
			// module的namefield
			FieldDefine fieldDefine = f.getAnnotation(FieldDefine.class);
			if (fieldDefine != null && fieldDefine.nameField()
					&& !f.getName().equals(module.getTf_nameFields())) {
				module.setTf_nameFields(f.getName());
				systemBaseDAO.attachDirty(module, null);
			}

			_ModuleField moduleField = (_ModuleField) systemBaseDAO
					.findByPropertyFirstWithOtherCondition(_ModuleField.class, _ModuleField.FIELDNAME,
							f.getName(), " tf_moduleId = '" + module.getTf_moduleId() + "'");
			boolean isnew = false;
			// 如果不是新加的字段，那么就不修改东西，如果要修改，自己去界面中修改
			if (moduleField == null) {
				isnew = true;
				moduleField = new _ModuleField();
				moduleField.setTf_Module(module);
				moduleField.setTf_fieldId(maxId);
				maxId += 10;
				moduleField.setTf_fieldName(f.getName());
				moduleField.setTf_allowNew(true);
				moduleField.setTf_allowEdit(true);
				i++;

				if (fieldDefine != null) {
					moduleField.setTf_title(fieldDefine.title());
					moduleField.setTf_fieldGroup(fieldDefine.fieldGroup());
					moduleField.setTf_isHidden(fieldDefine.hidden());
					moduleField
							.setTf_remark(fieldDefine.remark().length() == 0 ? null : fieldDefine.remark());
					moduleField.setTf_fieldOrder(fieldDefine.number());
				} else
					moduleField.setTf_title(f.getName());

				Column column = f.getAnnotation(Column.class);
				if (column != null) {
					moduleField.setTf_isRequired(!column.nullable());
					moduleField.setTf_fieldLen(column.length() == 255 ? null : column.length());
					moduleField.setTf_DBfieldName(column.name());
					moduleField.setTf_allowNew(column.insertable());
					moduleField.setTf_allowEdit(column.updatable());
				}

				Formula formula = f.getAnnotation(Formula.class);
				if (formula != null) {
					moduleField.setTf_DBformula(formula.value());
					moduleField.setTf_allowNew(false);
					moduleField.setTf_allowEdit(false);
				}

				moduleField.setTf_fieldType(f.getType().getSimpleName());

				if (f.getAnnotation(ManyToOne.class) != null) {
					moduleField.setTf_fieldRelation("ManyToOne");
					JoinColumn joinColumn = f.getAnnotation(JoinColumn.class);
					if (joinColumn != null) {
						moduleField.setTf_allowNew(joinColumn.insertable());
						moduleField.setTf_allowEdit(joinColumn.updatable());
						moduleField.setTf_isRequired(!joinColumn.nullable());
						moduleField.setTf_showNavigatorTree(true);
					}
				}

				if (moduleField.getTf_fieldName().equals(_InputInfoAbstract.INPUTMEN)
						|| moduleField.getTf_fieldName().equals(_InputInfoAbstract.INPUTDATE)) {
					moduleField.setTf_allowNew(false);
					moduleField.setTf_allowEdit(false);
					moduleField.setTf_isRequired(false);
				}

				if (f.getAnnotation(OneToOne.class) != null)
					moduleField.setTf_fieldRelation("OneToOne");
				if (f.getAnnotation(OneToMany.class) != null)
					moduleField.setTf_fieldRelation("OneToMany");
			}
			if (isnew)
				systemBaseDAO.save(moduleField);
			else
				systemBaseDAO.attachDirty(moduleField, null);
		}
		if (beanClass.getSuperclass() != null)
			return i + refreshModuleField(beanClass.getSuperclass(), module, maxId);
		else
			return i;
	}

	

	@Transactional(propagation = Propagation.REQUIRED)
	@Override
	public String addModuleWithName(String moduleName, Class<?> moduleClass, TableDefine tableDefine) {

		// 生成 模块文件
		_Module module = (_Module) systemBaseDAO.findByPropertyFirst(_Module.class, _Module.MODULENAME,
				moduleName);

		if (module == null) {
			module = new _Module();
			module.setTf_ModuleGroup(get_ModuleGroupWithTitle(tableDefine.group()));
			module.setTf_moduleId(String.valueOf(tableDefine.id()));
			module.setTf_moduleName(moduleName);
			module.setTf_shortname(tableDefine.shortname().length() > 1 ? tableDefine.shortname() : null);
			module.setTf_hasAddition(tableDefine.attachment());
			module.setTf_title(tableDefine.title());
			if (tableDefine.codeLevel().length() > 0)
				module.setTf_codeLevel(tableDefine.codeLevel());
			module.setTf_isEnable(true);
			module.setTf_hasBrowse(true);
			module.setTf_hasInsert(true);
			module.setTf_hasEdit(true);
			module.setTf_hasDelete(true);
			module.setTf_hasAuditing(false);
			module.setTf_hasApprove(false);
			module.setTf_isInlineOper(false);
			module.setTf_nameFields("undefined");
			module.setTf_primaryKey("undefined");
			module.setTf_requestMapping("undefined");
			systemBaseDAO.save(module);
		} else
			return "指定的类记录已经生成过了！";

		return null;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public Boolean createNewGridScheme(String moduleId, Class<?> moduleClass) {
		_Module module = (_Module) systemBaseDAO.findById(_Module.class, moduleId);
		if (module == null)
			return false;
		_ModuleGridScheme scheme = new _ModuleGridScheme();
		scheme.setTf_schemeName(module.getTf_title() + "列表");
		scheme.setTf_Module(module);
		scheme.setTf_schemeOrder(systemFrameDAO.getNextGridSchemeOrder(moduleId));
		systemBaseDAO.save(scheme);

		_ModuleGridSchemeGroup schemeGroup = new _ModuleGridSchemeGroup();
		schemeGroup.setTf_gridGroupOrder(1);
		schemeGroup.setTf_ModuleGridScheme(scheme);
		schemeGroup.setTf_gridGroupName(module.getTf_title());
		systemBaseDAO.save(schemeGroup);

		List<_ModuleField> fields = systemFrameDAO.get_ModuleFields(moduleId);

		int order = 10;
		for (_ModuleField field : fields) {
			if (field.getTf_isHidden())
				continue;
			// 审批的不加入，加入另外的组
			if (!(field.getTf_fieldOrder() >= 1000 && (field.getTf_fieldName().startsWith("tf_sh") || field
					.getTf_fieldName().startsWith("tf_auditing")))) {
				_ModuleGridSchemeGroupField groupField = new _ModuleGridSchemeGroupField();
				groupField.setTf_ModuleField(field);
				if (field.getTf_fieldOrder() != null && field.getTf_fieldOrder() > 0)
					groupField.setTf_gridFieldOrder(field.getTf_fieldOrder());
				else {
					groupField.setTf_gridFieldOrder(order);
					order += 10;
				}
				groupField.setTf_ModuleGridSchemeGroup(schemeGroup);
				systemBaseDAO.save(groupField);
			}
		}

		if (_AuditingAbstract.class.isAssignableFrom(moduleClass)) {
			// 审核组
			schemeGroup = new _ModuleGridSchemeGroup();
			schemeGroup.setTf_gridGroupOrder(8);
			schemeGroup.setTf_ModuleGridScheme(scheme);
			schemeGroup.setTf_isShowHeaderSpans(true);
			schemeGroup.setTf_gridGroupName("审核情况");
			systemBaseDAO.save(schemeGroup);
			order = 10;
			for (_ModuleField field : fields) {
				if ((field.getTf_fieldOrder() >= 2010 && field.getTf_fieldOrder() <= 2040)) {
					_ModuleGridSchemeGroupField groupField = new _ModuleGridSchemeGroupField();
					groupField.setTf_ModuleField(field);
					groupField.setTf_ModuleGridSchemeGroup(schemeGroup);
					if (field.getTf_fieldOrder() != null && field.getTf_fieldOrder() > 0)
						groupField.setTf_gridFieldOrder(field.getTf_fieldOrder());
					else {
						groupField.setTf_gridFieldOrder(order);
						order += 10;
					}
					systemBaseDAO.save(groupField);
				}
			}
		}

		if (_ApproveAbstract.class.isAssignableFrom(moduleClass))

			// 审批组
			for (int i = 1; i <= 6; i++) {
				schemeGroup = new _ModuleGridSchemeGroup();
				schemeGroup.setTf_gridGroupOrder(10 + i);
				schemeGroup.setTf_ModuleGridScheme(scheme);
				schemeGroup.setTf_isShowHeaderSpans(true);
				schemeGroup.setTf_gridGroupName("第" + i + "级审批");
				systemBaseDAO.save(schemeGroup);
				order = 10;
				for (_ModuleField field : fields) {
					if ((field.getTf_fieldOrder() >= 1000 + i * 100 && field.getTf_fieldOrder() < 1100 + i * 100)) {
						_ModuleGridSchemeGroupField groupField = new _ModuleGridSchemeGroupField();
						groupField.setTf_ModuleField(field);
						groupField.setTf_ModuleGridSchemeGroup(schemeGroup);
						if (field.getTf_fieldOrder() != null && field.getTf_fieldOrder() > 0)
							groupField.setTf_gridFieldOrder(field.getTf_fieldOrder());
						else {
							groupField.setTf_gridFieldOrder(order);
							order += 10;
						}
						systemBaseDAO.save(groupField);
					}
				}
			}
		return true;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public Boolean createNewFormScheme(String moduleId, Class<?> moduleClass) {
		_Module module = (_Module) systemBaseDAO.findById(_Module.class, moduleId);
		if (module == null)
			return false;
		_ModuleFormScheme scheme = new _ModuleFormScheme();
		scheme.setTf_schemeName(module.getTf_title() + "Form");
		scheme.setTf_Module(module);
		scheme.setTf_windowHeight(-1);
		scheme.setTf_windowWidth(600);
		scheme.setTf_numCols(2);
		scheme.setTf_schemeOrder(systemFrameDAO.getNextFormSchemeOrder(moduleId));
		systemBaseDAO.save(scheme);

		_ModuleFormSchemeGroup schemeGroup = new _ModuleFormSchemeGroup();
		schemeGroup.setTf_formGroupOrder(1);
		schemeGroup.setTf_ModuleFormScheme(scheme);
		schemeGroup.setTf_formGroupName(module.getTf_title());
		systemBaseDAO.save(schemeGroup);

		List<_ModuleField> fields = systemFrameDAO.get_ModuleFields(moduleId);

		int order = 10;
		for (_ModuleField field : fields) {
			if (!(field.getTf_fieldOrder() >= 1000 && (field.getTf_fieldName().startsWith("tf_sh") || field
					.getTf_fieldName().startsWith("tf_auditing")))) {
				_ModuleFormSchemeGroupField groupField = new _ModuleFormSchemeGroupField();
				groupField.setTf_ModuleField(field);
				groupField.setTf_ModuleFormSchemeGroup(schemeGroup);
				if (field.getTf_fieldOrder() != null && field.getTf_fieldOrder() > 0)
					groupField.setTf_formFieldOrder(field.getTf_fieldOrder());
				else {
					groupField.setTf_formFieldOrder(order);
					order += 10;
				}
				systemBaseDAO.save(groupField);
			}
		}

		// 审核组
		if (_AuditingAbstract.class.isAssignableFrom(moduleClass)) {
			schemeGroup = new _ModuleFormSchemeGroup();
			schemeGroup.setTf_formGroupOrder(8);
			schemeGroup.setTf_ModuleFormScheme(scheme);
			schemeGroup.setTf_auditingGroup(true);
			schemeGroup.setTf_numCols(2);
			schemeGroup.setTf_collapsible(true);
			schemeGroup.setTf_formGroupName("审核情况");
			systemBaseDAO.save(schemeGroup);
			order = 10;
			for (_ModuleField field : fields) {
				if ((field.getTf_fieldOrder() >= 2010 && field.getTf_fieldOrder() <= 2040)) {
					_ModuleFormSchemeGroupField groupField = new _ModuleFormSchemeGroupField();
					groupField.setTf_ModuleField(field);
					groupField.setTf_ModuleFormSchemeGroup(schemeGroup);
					if (field.getTf_fieldOrder() != null && field.getTf_fieldOrder() > 0)
						groupField.setTf_formFieldOrder(field.getTf_fieldOrder());
					else {
						groupField.setTf_formFieldOrder(order);
						order += 10;
					}
					systemBaseDAO.save(groupField);
				}
			}
		}

		// 审批组
		if (_ApproveAbstract.class.isAssignableFrom(moduleClass))
			for (int i = 1; i <= 6; i++) {
				schemeGroup = new _ModuleFormSchemeGroup();
				schemeGroup.setTf_formGroupOrder(10 + i);
				schemeGroup.setTf_ModuleFormScheme(scheme);
				schemeGroup.setTf_approveGroup(true);
				schemeGroup.setTf_numCols(3);
				schemeGroup.setTf_collapsible(true);
				schemeGroup.setTf_formGroupName("第" + i + "级审批");
				systemBaseDAO.save(schemeGroup);
				order = 10;
				for (_ModuleField field : fields) {
					if ((field.getTf_fieldOrder() >= 1000 + i * 100 && field.getTf_fieldOrder() < 1100 + i * 100)) {
						_ModuleFormSchemeGroupField groupField = new _ModuleFormSchemeGroupField();
						groupField.setTf_ModuleField(field);
						groupField.setTf_ModuleFormSchemeGroup(schemeGroup);
						if (field.getTf_fieldOrder() != null && field.getTf_fieldOrder() > 0)
							groupField.setTf_formFieldOrder(field.getTf_fieldOrder());
						else {
							groupField.setTf_formFieldOrder(order);
							order += 10;
						}
						systemBaseDAO.save(groupField);
					}
				}
			}
		return true;
	}

	
	private _ModuleGroup get_ModuleGroupWithTitle(String groupTitle) {
		_ModuleGroup moduleGroup = (_ModuleGroup) systemBaseDAO.findByPropertyFirst(_ModuleGroup.class,
				_ModuleGroup.TITLE, groupTitle);
		if (moduleGroup == null) {
			moduleGroup = new _ModuleGroup();
			moduleGroup.setTf_moduleGroupId(groupTitle);
			moduleGroup.setTf_title(groupTitle);
			systemBaseDAO.save(moduleGroup);
		}
		return moduleGroup;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	@Override
	public Boolean saveAdditionFields(String moduleName, String noderecords) {
		if (noderecords != null && noderecords.length() > 10) {
			JsonConfig config = new JsonConfig();
			config.setArrayMode(JsonConfig.MODE_OBJECT_ARRAY);
			config.setRootClass(TreeNodeRecordChecked.class);
			TreeNodeRecordChecked[] records = (TreeNodeRecordChecked[]) JSONSerializer.toJava(
					JSONArray.fromObject(noderecords), config);

			_Module module = SystemAndLoginInfoService.getModuleWithName(moduleName);
			for (TreeNodeRecordChecked record : records) {
				if (record.getTag() >= 0)
					systemFrameDAO.addorDeleteAdditionField(module.getTf_moduleId(),
							Integer.parseInt(record.getFieldvalue()),
							FieldAggregationType.values()[record.getTag()], record.getChecked());
			}
		}
		return true;
	}

	
	@Transactional(propagation = Propagation.REQUIRED)
	@Override
	public List<TreeNodeRecordChecked> getAllAdditionFields(String moduleName) {
		_Module module = SystemAndLoginInfoService.getModuleWithName(moduleName);
		String moduleId = module.getTf_moduleId();
		TreeNodeRecordChecked root = new TreeNodeRecordChecked(null, null, "所有可选择字段", null, null, null,
				null);
		root.setLeaf(false);
		// addModuleNameAndFieldtoTree(result, module);
		List<_Module> pModules = module.getAllParentsList();
		for (int i = 0; i < pModules.size(); i++) {
			root.getChildren().add(addModuleNameAndFieldtoTree(pModules.get(i), moduleId));
		}
		// 加入所有的childOneToOne 模块的字段
		for (_Module m : module.getChildOneToOnes())
			root.getChildren().add(addModuleNameAndFieldtoTree(m, moduleId));
		// 加入所有的parentOneToOne 模块的字段
		for (_Module m : module.getParentOneToOnes())
			root.getChildren().add(addModuleNameAndFieldtoTree(m, moduleId));
		// 加入所有可以统计个数的子模块
		pModules = module.getAllChildsList();
		TreeNodeRecordChecked countNode = new TreeNodeRecordChecked(null,
				FieldAggregationType.COUNT.getValue(), "可计数的模块", null, null, null, null);
		countNode.setLeaf(false);
		int count = 0;
		for (int i = 0; i < pModules.size(); i++) {
			TreeNodeRecordChecked node = new TreeNodeRecordChecked(pModules.get(i).getTf_moduleName(),
					null, pModules.get(i).getTf_title(), "count", pModules.get(i).getPrimaryKeyField()
							.getTf_fieldId().toString(), null, null);
			node.setTag(FieldAggregationType.COUNT.ordinal()); // 表示是计数的

			if (systemFrameDAO.isModuleHasAdditionField(moduleId, pModules.get(i).getPrimaryKeyField()
					.getTf_fieldId(), FieldAggregationType.COUNT))
				node.setChecked(true);

			count++;
			countNode.getChildren().add(node);
		}
		if (count > 0)
			root.getChildren().add(countNode);

		// 加入可以求合的所有子模块的字段
		TreeNodeRecordChecked sumNode = new TreeNodeRecordChecked(FieldAggregationType.SUM.getValue(),
				null, "可求和的字段", null, null, null, null);
		sumNode.setLeaf(false);

		count = 0;
		for (int i = 0; i < pModules.size(); i++) {
			TreeNodeRecordChecked r = addModuleNameAndsumFieldtoTree(pModules.get(i), moduleId);
			if (r != null)
				sumNode.getChildren().add(r);
		}
		if (sumNode.getChildren().size() > 0)
			root.getChildren().add(sumNode);

		List<TreeNodeRecordChecked> result = new ArrayList<TreeNodeRecordChecked>();
		autoAdjustParentChecked(root);
		result.add(root);
		return result;
	}

	
	private TreeNodeRecordChecked addModuleNameAndsumFieldtoTree(_Module module, String moduleId) {
		TreeNodeRecordChecked moduleRoot = new TreeNodeRecordChecked(module.getTf_moduleName(),
				module.getTableAsName(), module.getTf_title(), FieldAggregationType.SUM.getValue(), null,
				null, null);
		moduleRoot.setLeaf(false);
		for (_ModuleField field : module.getModuleFields()) {
			if (field.getTf_fieldType().equals(FieldType.Double) || field.getTf_allowSummary()) {
				TreeNodeRecordChecked record = new TreeNodeRecordChecked(module.getTf_moduleName(),
						module.getTableAsName(), field.getTf_title(), module.getTf_primaryKey(), field
								.getTf_fieldId().toString(), null, null);
				record.setTag(FieldAggregationType.SUM.ordinal()); // 表示是求和的
				if (systemFrameDAO.isModuleHasAdditionField(moduleId, field.getTf_fieldId(),
						FieldAggregationType.SUM))
					record.setChecked(true);
				moduleRoot.getChildren().add(record);
			}
		}
		if (moduleRoot.getChildren().size() > 0)
			return moduleRoot;
		else
			return null;
	}

	
	private TreeNodeRecordChecked addModuleNameAndFieldtoTree(_Module module, String moduleId) {

		TreeNodeRecordChecked moduleRoot = new TreeNodeRecordChecked(module.getTf_moduleName(),
				module.getTableAsName(), module.getTf_title(), null, null, null, null);
		moduleRoot.setLeaf(false);
		for (_ModuleField field : module.getModuleFields()) {
			if (!field.isManyToOne()) {
				TreeNodeRecordChecked record = new TreeNodeRecordChecked(module.getTf_moduleName(),
						module.getTableAsName(), field.getTf_title(), field.getTf_fieldName(), field
								.getTf_fieldId().toString(), null, null);
				record.setTag(FieldAggregationType.NORMAL.ordinal()); // 表示是正常的字段
				if (systemFrameDAO.isModuleHasAdditionField(moduleId, field.getTf_fieldId(),
						FieldAggregationType.NORMAL))
					record.setChecked(true);
				moduleRoot.getChildren().add(record);
			}
		}
		return moduleRoot;
	}

	
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<TreeNodeRecordChecked> getDetailGroupFields(String detailId) {
		log.debug("需要取得 detail group 的字段");
		Session session = systemBaseDAO.getSessionFactory().openSession();
		session.beginTransaction();
		TreeNodeRecordChecked root = new TreeNodeRecordChecked(null, null, "所有可选择字段", null, null, null,
				null);
		root.setLeaf(false);
		try {
			_ModuleDetailScheme group = (_ModuleDetailScheme) session.get(_ModuleDetailScheme.class,
					Integer.parseInt(detailId));
			_Module module = SystemAndLoginInfoService.getModuleWithName(group.getTf_Module()
					.getTf_moduleName());
			// 加入本模块所有可以使用的字段
			TreeNodeRecordChecked r = addModuleNameAndGroupFieldtoTree(module, null,
					Integer.parseInt(detailId), true, "detail");
			if (r != null)
				root.getChildren().add(r);
			// 加入所有父模块的字段
			List<_Module> pModules = module.getAllParentsList();
			for (int i = 0; i < pModules.size(); i++) {
				r = addModuleNameAndGroupFieldtoTree(pModules.get(i), module.getTf_moduleId(),
						Integer.parseInt(detailId), false, "detail");
				if (r != null)
					root.getChildren().add(r);
			}

			// 加入所有childOneToone字段
			pModules = module.getChildOneToOnes();
			for (int i = 0; i < pModules.size(); i++) {
				r = addModuleNameAndGroupFieldtoTree(pModules.get(i), module.getTf_moduleId(),
						Integer.parseInt(detailId), false, "detail");
				if (r != null)
					root.getChildren().add(r);
			}

			// 加入所有parentOneToone字段
			pModules = module.getParentOneToOnes();
			for (int i = 0; i < pModules.size(); i++) {
				r = addModuleNameAndGroupFieldtoTree(pModules.get(i), module.getTf_moduleId(),
						Integer.parseInt(detailId), false, "detail");
				if (r != null)
					root.getChildren().add(r);
			}

			// 加入子模块的count 字段
			pModules = module.getAllChildsList();
			TreeNodeRecordChecked countNode = new TreeNodeRecordChecked(
					FieldAggregationType.COUNT.getValue(), null, "可计数的模块", null, null, null, null);
			countNode.setLeaf(false);
			for (int j = 0; j < pModules.size(); j++)
				if (systemFrameDAO.isModuleHasAdditionField(module.getTf_moduleId(), pModules.get(j)
						.getPrimaryKeyField().getTf_fieldId(), FieldAggregationType.COUNT)) {
					TreeNodeRecordChecked node = new TreeNodeRecordChecked(
							pModules.get(j).getTf_moduleName(), null, pModules.get(j).getTf_title(), null,
							pModules.get(j).getPrimaryKeyField().getTf_fieldId().toString(), null, null);
					node.setTag(FieldAggregationType.COUNT.ordinal()); // 表示是计数的
					// 查找上count 字段是不是已经被选中了
					if (systemFrameDAO.isDetailGroupHasField(Integer.parseInt(detailId), pModules.get(j)
							.getPrimaryKeyField().getTf_fieldId()))
						node.setChecked(true);
					countNode.getChildren().add(node);
				}
			if (countNode.getChildren().size() > 0)
				root.getChildren().add(countNode);

			// ////
			// 加入子模块的已经选中可以被此模块使用的 sum 字段
			String moduleId = module.getTf_moduleId();

			TreeNodeRecordChecked sumNode = new TreeNodeRecordChecked(
					FieldAggregationType.SUM.getValue(), null, "可求和的字段", null, null, null, null);
			sumNode.setLeaf(false);
			for (int i = 0; i < pModules.size(); i++) {
				r = addModuleNameAndSelectedSumFieldtoTree(pModules.get(i), moduleId, detailId, true);
				if (r != null)
					sumNode.getChildren().add(r);
			}
			if (sumNode.getChildren().size() > 0)
				root.getChildren().add(sumNode);
		} finally {
			session.getTransaction().commit();
			session.close();
		}
		List<TreeNodeRecordChecked> result = new ArrayList<TreeNodeRecordChecked>();
		autoAdjustParentChecked(root);
		result.add(root);
		return result;
	}

	
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	@Override
	public List<TreeNodeRecordChecked> getGridGroupFields(String gridGroupId) {
		log.debug("需要取得grid group 的字段");
		Session session = systemBaseDAO.getSessionFactory().openSession();
		session.beginTransaction();
		TreeNodeRecordChecked root = new TreeNodeRecordChecked(null, null, "所有可选择字段", null, null, null,
				null);
		root.setLeaf(false);
		try {
			_ModuleGridSchemeGroup group = (_ModuleGridSchemeGroup) session.get(
					_ModuleGridSchemeGroup.class, Integer.parseInt(gridGroupId));
			_Module module = SystemAndLoginInfoService.getModuleWithName(group.getTf_ModuleGridScheme()
					.getTf_Module().getTf_moduleName());
			// 加入本模块所有可以使用的字段
			TreeNodeRecordChecked r = addModuleNameAndGroupFieldtoTree(module, null,
					Integer.parseInt(gridGroupId), true, "grid");
			if (r != null)
				root.getChildren().add(r);
			// 加入所有父模块的字段
			List<_Module> pModules = module.getAllParentsList();
			for (int i = 0; i < pModules.size(); i++) {
				r = addModuleNameAndGroupFieldtoTree(pModules.get(i), module.getTf_moduleId(),
						Integer.parseInt(gridGroupId), false, "grid");
				if (r != null)
					root.getChildren().add(r);
			}

			// 加入所有childOneToone字段
			pModules = module.getChildOneToOnes();
			for (int i = 0; i < pModules.size(); i++) {
				r = addModuleNameAndGroupFieldtoTree(pModules.get(i), module.getTf_moduleId(),
						Integer.parseInt(gridGroupId), false, "grid");
				if (r != null)
					root.getChildren().add(r);
			}

			// 加入所有parentOneToone字段
			pModules = module.getParentOneToOnes();
			for (int i = 0; i < pModules.size(); i++) {
				r = addModuleNameAndGroupFieldtoTree(pModules.get(i), module.getTf_moduleId(),
						Integer.parseInt(gridGroupId), false, "grid");
				if (r != null)
					root.getChildren().add(r);
			}

			// 加入子模块的count 字段
			pModules = module.getAllChildsList();
			TreeNodeRecordChecked countNode = new TreeNodeRecordChecked(
					FieldAggregationType.COUNT.getValue(), null, "可计数的模块", null, null, null, null);
			countNode.setLeaf(false);
			for (int j = 0; j < pModules.size(); j++)
				if (systemFrameDAO.isModuleHasAdditionField(module.getTf_moduleId(), pModules.get(j)
						.getPrimaryKeyField().getTf_fieldId(), FieldAggregationType.COUNT)) {
					TreeNodeRecordChecked node = new TreeNodeRecordChecked(
							pModules.get(j).getTf_moduleName(), null, pModules.get(j).getTf_title(), null,
							pModules.get(j).getPrimaryKeyField().getTf_fieldId().toString(), null, null);
					node.setTag(FieldAggregationType.COUNT.ordinal()); // 表示是计数的
					// 查找上count 字段是不是已经被选中了
					if (systemFrameDAO.isGridGroupHasField(Integer.parseInt(gridGroupId), pModules.get(j)
							.getPrimaryKeyField().getTf_fieldId()))
						node.setChecked(true);
					countNode.getChildren().add(node);
				}
			if (countNode.getChildren().size() > 0)
				root.getChildren().add(countNode);

			// ////
			// 加入子模块的已经选中可以被此模块使用的 sum 字段
			String moduleId = module.getTf_moduleId();

			TreeNodeRecordChecked sumNode = new TreeNodeRecordChecked(
					FieldAggregationType.SUM.getValue(), null, "可求和的字段", null, null, null, null);
			sumNode.setLeaf(false);
			for (int i = 0; i < pModules.size(); i++) {
				r = addModuleNameAndSelectedSumFieldtoTree(pModules.get(i), moduleId, gridGroupId, true);
				if (r != null)
					sumNode.getChildren().add(r);
			}
			if (sumNode.getChildren().size() > 0)
				root.getChildren().add(sumNode);
		} finally {
			session.getTransaction().commit();
			session.close();
		}
		List<TreeNodeRecordChecked> result = new ArrayList<TreeNodeRecordChecked>();
		autoAdjustParentChecked(root);
		result.add(root);
		return result;
	}

	
	private TreeNodeRecordChecked addModuleNameAndSelectedSumFieldtoTree(_Module module,
			String moduleId, String groupId, Boolean isgrid) {
		TreeNodeRecordChecked moduleRoot = new TreeNodeRecordChecked(module.getTf_moduleName(),
				module.getTableAsName(), module.getTf_title(), FieldAggregationType.SUM.getValue(), null,
				null, null);
		moduleRoot.setLeaf(false);
		for (_ModuleField field : module.getModuleFields()) {
			if (field.getTf_fieldType().equals(FieldType.Double) || field.getTf_allowSummary()) {
				if (systemFrameDAO.isModuleHasAdditionField(moduleId, field.getTf_fieldId(),
						FieldAggregationType.SUM)) {
					TreeNodeRecordChecked record = new TreeNodeRecordChecked(module.getTf_moduleName(),
							module.getTableAsName(), field.getTf_title(), module.getTf_primaryKey(), field
									.getTf_fieldId().toString(), null, null);
					record.setTag(FieldAggregationType.SUM.ordinal()); // 表示是求和的
					if (isgrid) {
						if (systemFrameDAO
								.isGridGroupHasField(Integer.parseInt(groupId), field.getTf_fieldId()))
							record.setChecked(true);
					} else {
						if (systemFrameDAO
								.isFormGroupHasField(Integer.parseInt(groupId), field.getTf_fieldId()))
							record.setChecked(true);
					}
					moduleRoot.getChildren().add(record);
				}
			}
		}
		if (moduleRoot.getChildren().size() > 0)
			return moduleRoot;
		else
			return null;
	}

	
	private TreeNodeRecordChecked addModuleNameAndGroupFieldtoTree(_Module module, String moduleId,
			Integer gridGroupId, boolean isThisModule, String what) {
		TreeNodeRecordChecked moduleRoot = new TreeNodeRecordChecked(module.getTf_moduleName(),
				module.getTableAsName(), module.getTf_title(), null, null, null, null);
		moduleRoot.setLeaf(false);
		for (_ModuleField field : module.getModuleFields()) {
			if (isThisModule
					|| systemFrameDAO.isModuleHasAdditionField(moduleId, field.getTf_fieldId(),
							FieldAggregationType.NORMAL)) {
				TreeNodeRecordChecked record = new TreeNodeRecordChecked(module.getTf_moduleName(),
						module.getTableAsName(), field.getTf_title(), module.getTf_primaryKey(), field
								.getTf_fieldId().toString(), null, null);
				record.setTag(FieldAggregationType.NORMAL.ordinal()); // 表示是正常的字段
				if (what.equals("grid")) {
					if (systemFrameDAO.isGridGroupHasField(gridGroupId, field.getTf_fieldId()))
						record.setChecked(true);
				} else if (what.equals("form")) {
					if (systemFrameDAO.isFormGroupHasField(gridGroupId, field.getTf_fieldId()))
						record.setChecked(true);
				} else if (what.equals("detail")) {
					if (systemFrameDAO.isDetailGroupHasField(gridGroupId, field.getTf_fieldId()))
						record.setChecked(true);
				}
				moduleRoot.getChildren().add(record);
			}
		}
		if (moduleRoot.getChildren().size() > 0)
			return moduleRoot;
		else
			return null;
	}

	
	@Transactional(propagation = Propagation.REQUIRED)
	@Override
	public Boolean saveGridGroupFields(String gridGroupId, String noderecords) {
		if (noderecords != null && noderecords.length() > 10) {
			JsonConfig config = new JsonConfig();
			config.setArrayMode(JsonConfig.MODE_OBJECT_ARRAY);
			config.setRootClass(TreeNodeRecordChecked.class);
			TreeNodeRecordChecked[] records = (TreeNodeRecordChecked[]) JSONSerializer.toJava(
					JSONArray.fromObject(noderecords), config);

			for (TreeNodeRecordChecked record : records) {
				if (record.getFieldvalue() != null)
					systemFrameDAO.addorDeleteGridGroupFields(Integer.parseInt(gridGroupId),
							Integer.parseInt(record.getFieldvalue()), record.getChecked());
			}
		}
		SystemAndLoginInfoService.setRefreshAll(true);
		return true;
	}

	
	@Transactional(propagation = Propagation.REQUIRED)
	public Boolean saveDetailGroupFields(String detailId, String noderecords) {
		if (noderecords != null && noderecords.length() > 10) {
			JsonConfig config = new JsonConfig();
			config.setArrayMode(JsonConfig.MODE_OBJECT_ARRAY);
			config.setRootClass(TreeNodeRecordChecked.class);
			TreeNodeRecordChecked[] records = (TreeNodeRecordChecked[]) JSONSerializer.toJava(
					JSONArray.fromObject(noderecords), config);

			for (TreeNodeRecordChecked record : records) {
				if (record.getFieldvalue() != null)
					systemFrameDAO.addorDeleteDetailGroupFields(Integer.parseInt(detailId),
							Integer.parseInt(record.getFieldvalue()), record.getChecked());
			}
		}
		SystemAndLoginInfoService.setRefreshAll(true);
		return true;
	}

	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	@Override
	public List<TreeNodeRecordChecked> getFormGroupFields(String formGroupId) {

		log.debug("需要取得grid group 的字段");
		Session session = systemBaseDAO.getSessionFactory().openSession();
		session.beginTransaction();
		TreeNodeRecordChecked root = new TreeNodeRecordChecked(null, null, "所有可选择字段", null, null, null,
				null);
		root.setLeaf(false);
		try {
			_ModuleFormSchemeGroup group = (_ModuleFormSchemeGroup) session.get(
					_ModuleFormSchemeGroup.class, Integer.parseInt(formGroupId));
			_Module module = SystemAndLoginInfoService.getModuleWithName(group.getTf_ModuleFormScheme()
					.getTf_Module().getTf_moduleName());
			// 加入本模块所有可以使用的字段
			TreeNodeRecordChecked r = addModuleNameAndGroupFieldtoTree(module, null,
					Integer.parseInt(formGroupId), true, "form");
			if (r != null)
				root.getChildren().add(r);

			// 加入所有父模块的字段
			List<_Module> pModules = module.getAllParentsList();
			for (int i = 0; i < pModules.size(); i++) {
				r = addModuleNameAndGroupFieldtoTree(pModules.get(i), module.getTf_moduleId(),
						Integer.parseInt(formGroupId), false, "form");
				if (r != null)
					root.getChildren().add(r);
			}
			
			

			// 加入所有childOneToone字段
			pModules = module.getChildOneToOnes();
			for (int i = 0; i < pModules.size(); i++) {
				r = addModuleNameAndGroupFieldtoTree(pModules.get(i), module.getTf_moduleId(),
						Integer.parseInt(formGroupId), false, "form");
				if (r != null)
					root.getChildren().add(r);
			}

			// 加入所有parentOneToone字段
			pModules = module.getParentOneToOnes();
			for (int i = 0; i < pModules.size(); i++) {
				r = addModuleNameAndGroupFieldtoTree(pModules.get(i), module.getTf_moduleId(),
						Integer.parseInt(formGroupId), false, "form");
				if (r != null)
					root.getChildren().add(r);
			}
			
			
			
			
			// 加入子模块的count 字段
			pModules = module.getAllChildsList();
			TreeNodeRecordChecked countNode = new TreeNodeRecordChecked(
					FieldAggregationType.COUNT.getValue(), null, "可计数的模块", null, null, null, null);
			countNode.setLeaf(false);
			for (int j = 0; j < pModules.size(); j++)
				if (systemFrameDAO.isModuleHasAdditionField(module.getTf_moduleId(), pModules.get(j)
						.getPrimaryKeyField().getTf_fieldId(), FieldAggregationType.COUNT)) {
					TreeNodeRecordChecked node = new TreeNodeRecordChecked(
							pModules.get(j).getTf_moduleName(), null, pModules.get(j).getTf_title(), null,
							pModules.get(j).getPrimaryKeyField().getTf_fieldId().toString(), null, null);
					node.setTag(FieldAggregationType.COUNT.ordinal()); // 表示是计数的
					// 查找上count 字段是不是已经被选中了
					if (systemFrameDAO.isFormGroupHasField(Integer.parseInt(formGroupId), pModules.get(j)
							.getPrimaryKeyField().getTf_fieldId()))
						node.setChecked(true);
					countNode.getChildren().add(node);
				}
			if (countNode.getChildren().size() > 0)
				root.getChildren().add(countNode);
			// ////
			// 加入子模块的已经选中可以被此模块使用的 sum 字段
			String moduleId = module.getTf_moduleId();
			TreeNodeRecordChecked sumNode = new TreeNodeRecordChecked(
					FieldAggregationType.SUM.getValue(), null, "可求和的字段", null, null, null, null);
			for (int i = 0; i < pModules.size(); i++) {
				r = addModuleNameAndSelectedSumFieldtoTree(pModules.get(i), moduleId, formGroupId, false);
				if (r != null)
					sumNode.getChildren().add(r);
			}
			if (sumNode.getChildren().size() > 0)
				root.getChildren().add(sumNode);
		} finally {
			session.getTransaction().commit();
			session.close();
		}
		List<TreeNodeRecordChecked> result = new ArrayList<TreeNodeRecordChecked>();
		autoAdjustParentChecked(root);
		result.add(root);
		return result;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	@Override
	public Boolean saveFormGroupFields(String formGroupId, String noderecords) {
		if (noderecords != null && noderecords.length() > 10) {
			JsonConfig config = new JsonConfig();
			config.setArrayMode(JsonConfig.MODE_OBJECT_ARRAY);
			config.setRootClass(TreeNodeRecordChecked.class);
			TreeNodeRecordChecked[] records = (TreeNodeRecordChecked[]) JSONSerializer.toJava(
					JSONArray.fromObject(noderecords), config);

			for (TreeNodeRecordChecked record : records) {
				if (record.getFieldvalue() != null)
					systemFrameDAO.addorDeleteFormGroupFields(Integer.parseInt(formGroupId),
							Integer.parseInt(record.getFieldvalue()), record.getChecked());
			}
		}
		SystemAndLoginInfoService.setRefreshAll(true);
		return true;

	}

	
	private boolean autoAdjustParentChecked(TreeNodeRecordChecked node) {
		boolean checked = true;
		if (node.hasChildren()) {
			for (TreeNodeRecord c : node.getChildren())
				checked = checked && autoAdjustParentChecked((TreeNodeRecordChecked) c);
			node.setChecked(checked);
		}
		return node.getChecked();
	}

}
